using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using AutoMapper;
using CR.Domain.Entities;
using CR.Application.DTOs;
using CR.Application.Interfaces;
using CR.Infrastructure.Repositories;
using CR.ErrorCode;

namespace CR.Application.Services
{
    /// <summary>
    /// 溯源管理服务实现
    /// </summary>
    public class TraceabilityService : ITraceabilityService
    {
        private readonly ITraceabilityRepository _traceabilityRepository;
        private readonly IMapper _mapper;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="traceabilityRepository">溯源管理仓储</param>
        /// <param name="mapper">对象映射器</param>
        public TraceabilityService(ITraceabilityRepository traceabilityRepository, IMapper mapper)
        {
            _traceabilityRepository = traceabilityRepository ?? throw new ArgumentNullException(nameof(traceabilityRepository));
            _mapper = mapper ?? throw new ArgumentNullException(nameof(mapper));
        }

        /// <inheritdoc/>
        public async Task<ApiResult<IEnumerable<TraceabilityManagementDTO>>> GetAllTraceabilityAsync()
        {
            try
            {
                var traceabilityList = await _traceabilityRepository.GetAllActiveAsync();
                var traceabilityDTOs = _mapper.Map<IEnumerable<TraceabilityManagementDTO>>(traceabilityList);
                
                return ApiResult<IEnumerable<TraceabilityManagementDTO>>.Success(traceabilityDTOs, "获取溯源管理记录列表成功");
            }
            catch (Exception ex)
            {
                return ApiResult<IEnumerable<TraceabilityManagementDTO>>.Fail(ApiEnums.SystemError, $"获取溯源管理记录列表失败: {ex.Message}");
            }
        }

        /// <inheritdoc/>
        public async Task<ApiResult<TraceabilityManagementDTO>> GetTraceabilityByIdAsync(int id)
        {
            try
            {
                var traceability = await _traceabilityRepository.GetByIdAsync(id);
                if (traceability == null || traceability.IsDeleted == 1)
                {
                    return ApiResult<TraceabilityManagementDTO>.Fail(ApiEnums.NotFound, "溯源管理记录不存在");
                }

                var traceabilityDTO = _mapper.Map<TraceabilityManagementDTO>(traceability);
                return ApiResult<TraceabilityManagementDTO>.Success(traceabilityDTO, "获取溯源管理记录详情成功");
            }
            catch (Exception ex)
            {
                return ApiResult<TraceabilityManagementDTO>.Fail(ApiEnums.SystemError, $"获取溯源管理记录详情失败: {ex.Message}");
            }
        }

        /// <inheritdoc/>
        public async Task<ApiResult<TraceabilityManagementDTO>> GetTraceabilityByCodeAsync(string traceabilityCode)
        {
            try
            {
                if (string.IsNullOrWhiteSpace(traceabilityCode))
                {
                    return ApiResult<TraceabilityManagementDTO>.Fail(ApiEnums.ParameterError, "溯源码不能为空");
                }

                var traceability = await _traceabilityRepository.GetByTraceabilityCodeAsync(traceabilityCode);
                if (traceability == null || traceability.IsDeleted == 1)
                {
                    return ApiResult<TraceabilityManagementDTO>.Fail(ApiEnums.NotFound, "溯源管理记录不存在");
                }

                var traceabilityDTO = _mapper.Map<TraceabilityManagementDTO>(traceability);
                return ApiResult<TraceabilityManagementDTO>.Success(traceabilityDTO, "获取溯源管理记录详情成功");
            }
            catch (Exception ex)
            {
                return ApiResult<TraceabilityManagementDTO>.Fail(ApiEnums.SystemError, $"获取溯源管理记录详情失败: {ex.Message}");
            }
        }

        /// <inheritdoc/>
        public async Task<ApiResult<TraceabilityManagementDTO>> CreateTraceabilityAsync(TraceabilityCreateDTO createDto)
        {
            try
            {
                // 检查是否提供了必要信息
                if (createDto == null)
                {
                    return ApiResult<TraceabilityManagementDTO>.Fail(ApiEnums.ParameterError, "提供的溯源管理信息不能为空");
                }
                
                // 检查溯源码唯一性
                if (!string.IsNullOrWhiteSpace(createDto.TraceabilityCode))
                {
                    bool codeExists = await _traceabilityRepository.ExistsTraceabilityCodeAsync(createDto.TraceabilityCode);
                    if (codeExists)
                    {
                        return ApiResult<TraceabilityManagementDTO>.Fail(ApiEnums.BadRequest, "溯源码已存在");
                    }
                }
                else
                {
                    // 自动生成溯源码
                    createDto.TraceabilityCode = GenerateTraceabilityCode();
                }
                
                // 映射并设置初始值
                var traceability = _mapper.Map<TraceabilityManagement>(createDto);
                traceability.CreateTime = DateTime.Now;
                traceability.UpdateTime = DateTime.Now;
                traceability.IsDeleted = 0;
                
                // 计算信息完整度
                traceability.CompletenessScore = CalculateCompletenessScore(createDto);

                // 保存到数据库
                var createdTraceability = await _traceabilityRepository.AddAsync(traceability);
                var traceabilityDTO = _mapper.Map<TraceabilityManagementDTO>(createdTraceability);
                
                return ApiResult<TraceabilityManagementDTO>.Success(traceabilityDTO, "创建溯源管理记录成功");
            }
            catch (Exception ex)
            {
                return ApiResult<TraceabilityManagementDTO>.Fail(ApiEnums.SystemError, $"创建溯源管理记录失败: {ex.Message}");
            }
        }
        
        /// <summary>
        /// 计算信息完整度得分
        /// </summary>
        /// <param name="dto">溯源创建DTO</param>
        /// <returns>完整度得分(0-100)</returns>
        private int CalculateCompletenessScore(TraceabilityCreateDTO dto)
        {
            int totalFields = 7; // 调整为7个关键字段
            int completedFields = 0;
            
            if (!string.IsNullOrWhiteSpace(dto.ProductName)) completedFields++;
            if (!string.IsNullOrWhiteSpace(dto.TraceabilityCode)) completedFields++;
            if (dto.ProductionBatch != default(DateTime)) completedFields++;
            if (dto.ShelfLife > 0) completedFields++;
            if (!string.IsNullOrWhiteSpace(dto.ProductionLicenseNumber)) completedFields++;
            if (!string.IsNullOrWhiteSpace(dto.ProductionCompany)) completedFields++;
            if (dto.ProductionDate.HasValue) completedFields++;
            
            return (int)Math.Round(((double)completedFields / totalFields) * 100);
        }
        
        /// <summary>
        /// 生成唯一的溯源码
        /// </summary>
        /// <returns>溯源码</returns>
        private string GenerateTraceabilityCode()
        {
            // 生成一个基于当前时间和随机数的唯一码
            string timestamp = DateTime.Now.ToString("yyyyMMddHHmmss");
            string randomPart = new Random().Next(1000, 9999).ToString();
            return $"TC{timestamp}{randomPart}";
        }

        /// <inheritdoc/>
        public async Task<ApiResult<TraceabilityManagementDTO>> UpdateTraceabilityAsync(int id, TraceabilityUpdateDTO updateDto)
        {
            try
            {
                // 检查记录是否存在
                var existingTraceability = await _traceabilityRepository.GetByIdAsync(id);
                if (existingTraceability == null || existingTraceability.IsDeleted == 1)
                {
                    return ApiResult<TraceabilityManagementDTO>.Fail(ApiEnums.NotFound, "溯源管理记录不存在");
                }
                
                // 检查溯源码唯一性
                if (!string.IsNullOrWhiteSpace(updateDto.TraceabilityCode) && 
                    updateDto.TraceabilityCode != existingTraceability.TraceabilityCode)
                {
                    bool codeExists = await _traceabilityRepository.ExistsTraceabilityCodeAsync(updateDto.TraceabilityCode);
                    if (codeExists)
                    {
                        return ApiResult<TraceabilityManagementDTO>.Fail(ApiEnums.BadRequest, "溯源码已存在");
                    }
                }

                // 更新实体
                _mapper.Map(updateDto, existingTraceability);
                existingTraceability.UpdateTime = DateTime.Now;
                
                // 直接计算完整度得分
                int completedFields = 0;
                int totalFields = 7;
                
                if (!string.IsNullOrWhiteSpace(updateDto.ProductName)) completedFields++;
                if (!string.IsNullOrWhiteSpace(updateDto.TraceabilityCode)) completedFields++;
                if (updateDto.ProductionBatch != default(DateTime)) completedFields++;
                if (updateDto.ShelfLife > 0) completedFields++;
                if (!string.IsNullOrWhiteSpace(updateDto.ProductionLicenseNumber)) completedFields++;
                if (!string.IsNullOrWhiteSpace(updateDto.ProductionCompany)) completedFields++;

                existingTraceability.CompletenessScore = (int)Math.Round(((double)completedFields / totalFields) * 100);

                // 保存到数据库
                var updatedTraceability = await _traceabilityRepository.UpdateAsync(existingTraceability);
                var traceabilityDTO = _mapper.Map<TraceabilityManagementDTO>(updatedTraceability);
                
                return ApiResult<TraceabilityManagementDTO>.Success(traceabilityDTO, "更新溯源管理记录成功");
            }
            catch (Exception ex)
            {
                return ApiResult<TraceabilityManagementDTO>.Fail(ApiEnums.SystemError, $"更新溯源管理记录失败: {ex.Message}");
            }
        }

        /// <inheritdoc/>
        public async Task<ApiResult> DeleteTraceabilityAsync(int id)
        {
            try
            {
                // 检查记录是否存在
                var existingTraceability = await _traceabilityRepository.GetByIdAsync(id);
                if (existingTraceability == null || existingTraceability.IsDeleted == 1)
                {
                    return ApiResult.Fail(ApiEnums.NotFound, "溯源管理记录不存在");
                }

                // 逻辑删除
                existingTraceability.IsDeleted = 1;
                existingTraceability.UpdateTime = DateTime.Now;
                await _traceabilityRepository.UpdateAsync(existingTraceability);

                return ApiResult.Success("溯源管理记录删除成功");
            }
            catch (Exception ex)
            {
                return ApiResult.Fail(ApiEnums.SystemError, $"删除溯源管理记录失败: {ex.Message}");
            }
        }

        /// <inheritdoc/>
        public async Task<ApiResult> BatchDeleteTraceabilityAsync(IEnumerable<int> ids)
        {
            try
            {
                if (ids == null || !ids.Any())
                {
                    return ApiResult.Fail(ApiEnums.BadRequest, "没有提供要删除的ID");
                }

                // 执行批量删除
                var result = await _traceabilityRepository.BatchDeleteAsync(ids);
                
                return result 
                    ? ApiResult.Success("溯源管理记录批量删除成功") 
                    : ApiResult.Fail(ApiEnums.SystemError, "批量删除失败，请检查ID是否存在");
            }
            catch (Exception ex)
            {
                return ApiResult.Fail(ApiEnums.SystemError, $"批量删除溯源管理记录失败: {ex.Message}");
            }
        }

        /// <inheritdoc/>
        public async Task<ApiResult<ApiPagin<TraceabilityManagementDTO>>> GetPagedTraceabilityAsync(TraceabilityQueryDTO query)
        {
            try
            {
                // 参数验证
                if (query.PageIndex < 1)
                    query.PageIndex = 1;
                
                if (query.PageSize < 1)
                    query.PageSize = 10;

                // 执行高级查询
                var (data, total) = await _traceabilityRepository.GetPagedTraceabilityAsync(
                    query.PageIndex,
                    query.PageSize,
                    query.ProductName,
                    query.ProductionBatchStart,
                    query.ProductionBatchEnd,
                    query.ShelfLifeMin,
                    query.ShelfLifeMax,
                    query.ProductionLicenseNumber,
                    query.ProductionCompany);

                // 映射到DTO
                var traceabilityDtos = _mapper.Map<IEnumerable<TraceabilityManagementDTO>>(data);

                // 构建分页结果
                var pagedResult = new ApiPagin<TraceabilityManagementDTO>
                {
                    PageIndex = query.PageIndex,
                    PageSize = query.PageSize,
                    TotalCount = total,
                    TotalPages = (int)Math.Ceiling(total / (double)query.PageSize),
                    Items = traceabilityDtos
                };

                return ApiResult<ApiPagin<TraceabilityManagementDTO>>.Success(pagedResult, "获取溯源管理记录分页数据成功");
            }
            catch (Exception ex)
            {
                return ApiResult<ApiPagin<TraceabilityManagementDTO>>.Fail(ApiEnums.SystemError, $"获取溯源管理记录分页数据失败: {ex.Message}");
            }
        }
    }
} 